#include "D3DXDevice.h"

//--------------------------------------------------------------------
D3DXDevice::D3DXDevice()
{
	m_driverType		= D3D_DRIVER_TYPE_NULL;
	m_featureLevel		= D3D_FEATURE_LEVEL_11_0;
	m_pd3dDevice		= NULL;
	m_pImmediateContext	= NULL;
	m_pSwapChain		= NULL;

	m_pVertexBuffer		= NULL;
}

//--------------------------------------------------------------------
D3DXDevice::~D3DXDevice()
{

}

//--------------------------------------------------------------------
HRESULT D3DXDevice::InitDevice( HWND hWnd )
{
	D3D_DRIVER_TYPE driverTypes[] = 
	{
		D3D_DRIVER_TYPE_HARDWARE,
		D3D_DRIVER_TYPE_WARP,
		D3D_DRIVER_TYPE_REFERENCE,
	};

	D3D_FEATURE_LEVEL featureLevels[] = 
	{
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0,
		D3D_FEATURE_LEVEL_9_3,
		D3D_FEATURE_LEVEL_9_2,
		D3D_FEATURE_LEVEL_9_1,
	};

	HRESULT hr = S_OK;

	RECT rc;
	GetClientRect( hWnd, &rc );
	UINT width	= rc.right - rc.left;
	UINT height	= rc.bottom - rc.top;

	UINT createDeviceFlags = 0;

#ifdef _DEBUG
	createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	UINT numDriverTypes = ARRAYSIZE( driverTypes );

	UINT numFeatureLevels = ARRAYSIZE( featureLevels );

	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory( &sd, sizeof( sd ) );
	sd.BufferCount							= 1;
	sd.BufferDesc.Width						= width;
	sd.BufferDesc.Height					= height;
	sd.BufferDesc.Format					= DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator		= 60;
	sd.BufferDesc.RefreshRate.Denominator	= 1;
	sd.BufferUsage							= DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow							= hWnd;
	sd.SampleDesc.Count						= 1;
	sd.SampleDesc.Quality					= 0;
	sd.Windowed								= TRUE;

	for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
	{
		m_driverType = driverTypes[driverTypeIndex];
		hr = D3D11CreateDeviceAndSwapChain( NULL, m_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
			D3D11_SDK_VERSION, &sd, &m_pSwapChain, &m_pd3dDevice, &m_featureLevel, &m_pImmediateContext );
		if( SUCCEEDED( hr ) )
			break;
	}

	if( FAILED( hr ) )
		return hr;

	return S_OK;
}

//--------------------------------------------------------------------
void D3DXDevice::CleanupDevice()
{
	if( m_pImmediateContext )	m_pImmediateContext->ClearState();
	if( m_pSwapChain )			m_pSwapChain->Release();
	if( m_pImmediateContext )	m_pImmediateContext->Release();
	if( m_pd3dDevice )			m_pd3dDevice->Release();
}

//--------------------------------------------------------------------
ID3D11Device* D3DXDevice::GetDevice()
{
	return m_pd3dDevice;
}
//--------------------------------------------------------------------
ID3D11DeviceContext* D3DXDevice::GetDeviceContext()
{
	return m_pImmediateContext;
}

//--------------------------------------------------------------------
IDXGISwapChain* D3DXDevice::GetSwapChain()
{
	return m_pSwapChain;
}

//--------------------------------------------------------------------
HRESULT D3DXDevice::CreateVertexBuffer()
{
	HRESULT hr;

	aeBaseVertex vertices[] = 
	{
		XMFLOAT3( 0.0f, 0.5f, 0.5f ),
		XMFLOAT3( 0.5f, -0.5f, 0.5f ),
		XMFLOAT3( -0.0f, -0.5f, 0.5f ),
	};

	D3D11_BUFFER_DESC bd;
	ZeroMemory( &bd, sizeof(bd) );
	bd.Usage			= D3D11_USAGE_DEFAULT;
	bd.ByteWidth		= sizeof( aeBaseVertex ) * 3;
	bd.BindFlags		= D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags	= 0;

	D3D11_SUBRESOURCE_DATA InitData;
	ZeroMemory( &InitData, sizeof(InitData) );
	InitData.pSysMem = vertices;

	hr = m_pd3dDevice->CreateBuffer( &bd, &InitData, &m_pVertexBuffer );
	if( FAILED(hr) )
		return hr;

	return S_OK;
}